package com.suixuan.support.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;

import com.suixuan.support.log.LogConstant;
import com.suixuan.support.log.LogFactory;

/**
 * Nanjing Zhou Su co.,Ltd
 * 
 * @Title: FileUtils.java
 * @Package: com.suixuan.spring.util
 * @Description: 加载配置文件
 * @Author: suixuan
 * @Date 2010-3-15 下午04:00:46
 * @Version V1.0
 */
public final class FileUtils {
	/**
	 * 加载properties文件 by suixuan begin
	 */
	private static Properties props = new Properties();

	/**
	 * 加载配置的Mini类型文件
	 */
	private static Map<String, String[]> miniConfig = new HashMap<String, String[]>();

	static {
		try {
			props = PropertiesLoaderUtils.loadAllProperties("oa.properties");
		} catch (IOException e) {
			// 记录加载资源文件失败日志
			LogFactory.getInstance(FileUtils.class).logRecord(LogConstant.ERROR, e.toString(), e);
		}
	}

	/**
	 * 从HttpServletRequest中获取上传文件
	 * 
	 * @param request
	 *            {@link HttpServletRequest}
	 * @return 有效的上传文件列表
	 * @throws FileUploadException
	 */
	@SuppressWarnings("unchecked")
	public static List<FileItem> getUpLoadFileByRequest(HttpServletRequest request) throws FileUploadException {
		Assert.notNull(request, "HttpServletRequest为空");
		// if (request.getClass() != HttpServletRequest.class) {
		// throw new FileUploadException("request非原生的HttpServletRequest类型");
		// }

		DiskFileItemFactory fac = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(fac);
		upload.setHeaderEncoding(ConstantUtils.ENCODER_UTF_8);
		List<FileItem> fileList = upload.parseRequest(request);
		List<FileItem> listFileItem = new ArrayList<FileItem>();
		Iterator<FileItem> it = fileList.iterator();
		while (it.hasNext()) {
			FileItem item = it.next();
			if (!item.isFormField()) {
				listFileItem.add(item);
			}
		}
		return listFileItem;
	}

	/**
	 * 获取文件后缀
	 * 
	 * @param fileName
	 *            文件名
	 */
	public static String getFilePostfix(String fileName) {
		Assert.hasText(fileName, "文件名为空");
		int len = fileName.lastIndexOf(".");
		if (-1 == len) {
			return fileName;
		}
		return fileName.substring(fileName.lastIndexOf("."), fileName.length());
	}

	/**
	 * 获取oa.properties配置项的值
	 * 
	 * @param key
	 *            配置项的键值
	 * @return 配置项的Value值
	 */
	public static String getProperties(String key) {
		return (String) props.get(key);
	}

	/**
	 * 获取oa.properties配置项的值，返回Int值
	 * 
	 * @param key
	 *            配置项的键值
	 * @return 配置项的Value值
	 */
	public static int getIntProperties(String key) {
		String value = props.getProperty(key);
		if (!StringUtils.hasText(value)) {
			return 0;
		}
		if (!SecurityUtils.matchNumber(value)) {
			return 0;
		}
		return Integer.parseInt(value);
	}

	/**
	 * 获取oa.properties配置项的值，返回Long值
	 * 
	 * @param key
	 *            配置项的键值
	 * @return 配置项的Value值
	 */
	public static long getLongProperties(String key) {
		String value = props.getProperty(key);
		if (!StringUtils.hasText(value)) {
			return 0;
		}
		if (!SecurityUtils.matchNumber(value)) {
			return 0;
		}
		return Long.parseLong(value);
	}

	/**
	 * 获取oa.properties配置项的值，返回Float值
	 * 
	 * @param key
	 *            配置项的键值
	 * @return 配置项的Value值
	 */
	public static float getFloatProperties(String key) {
		String value = props.getProperty(key);
		if (!StringUtils.hasText(value)) {
			return 0;
		}
		if (!SecurityUtils.matchNumber(value)) {
			return 0;
		}
		return Float.parseFloat(value);
	}

	/**
	 * 获取oa.properties配置项的值，返回Double值
	 * 
	 * @param key
	 *            配置项的键值
	 * @return 配置项的Value值
	 */
	public static Double getDoubleProperties(String key) {
		String value = props.getProperty(key);
		if (!StringUtils.hasText(value)) {
			return 0D;
		}
		if (!SecurityUtils.matchNumber(value)) {
			return 0D;
		}
		return Double.parseDouble(value);
	}

	/**
	 * 获取oa.properties配置项的值，返回Boolean值
	 * 
	 * @param key
	 *            配置项的键值
	 * @return 配置项的Value值
	 */
	public static boolean getBooleanProperties(String key) {
		String value = props.getProperty(key);
		if (ConstantUtils.TRUE_STRING.equalsIgnoreCase(value) || ConstantUtils.FALSE_STRING.equalsIgnoreCase(value)) {
			return Boolean.parseBoolean(value);
		}
		return Boolean.FALSE;
	}

	/**
	 * 加载properties文件 by suixuan end
	 */

	/**
	 * 私有构造方法，工具类
	 */
	private FileUtils() {
		super();
	}

	/**
	 * 返回是否是合法的文件后缀
	 * 
	 * @param legitimateSuffix
	 *            合法的后缀集
	 * @param suffix
	 *            当前文件后缀
	 * @return 合法：True，不合法：False
	 */
	public static boolean legitimateFileSuffix(String legitimateSuffix, String suffix) {
		return legitimateFileSuffix(legitimateSuffix.split(ConstantUtils.SPLIT_KEY), suffix);
	}

	/**
	 * 文件夹打Zip包，仅支持一层目录
	 * 
	 * @param zipFilePath
	 *            打包后的文件路径
	 * @param filesPath
	 *            被打包的文件夹
	 * @param zipFileName
	 *            需被打包的文件，空集合为文件夹全部文件
	 * @throws IOException
	 */
	public static void zipFiles(String zipFilePath, String filesPath, final List<String> zipFileName)
			throws IOException {

		BufferedInputStream origin = null;
		ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFilePath)));
		out.setEncoding(ConstantUtils.ENCODER_GBK);
		out.setMethod(ZipOutputStream.DEFLATED);
		int size = 4082;
		byte data[] = new byte[size];
		// get a list of files from filesPath
		File f = new File(filesPath);
		String files[] = !CollectionUtils.isEmpty(zipFileName) ? f.list() : f.list(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				if (zipFileName.contains(name)) {
					return true;
				}
				return false;
			}
		});
		File temp = null;
		for (int i = 0; i < files.length; i++) {
			// 目录
			temp = new File(filesPath + File.separator + files[i]);
			if (temp.isDirectory()) {
				continue;
			}

			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(filesPath + File.separator + files[i]));

			origin = new BufferedInputStream(bis, size);
			ZipEntry entry = new ZipEntry(files[i]);

			out.putNextEntry(entry);
			int count = 0;
			while (-1 != (count = origin.read(data, 0, size))) {

				out.write(data, 0, count);
			}
			origin.close();
		}
		out.close();

	}

	/**
	 * 文件夹打Zip包，支持多层目录
	 * 
	 * @param zipFilePath
	 *            打包后的文件路径
	 * @param filesPath
	 *            被打包的文件夹
	 * @throws FileReadException
	 */
	public static void zipFiles(String zipFilePath, String filesPath) {
		Assert.hasText(zipFilePath, "打Zip包文件目标路径为空");
		Assert.hasText(filesPath, "打Zip包文件源路径为空");
		// 创建目录
		File zipFile = new File(zipFilePath.substring(0, zipFilePath.lastIndexOf(File.separator)));
		if (!zipFile.canRead()) {
			if (!zipFile.mkdirs()) {

			}
		}
		// 创建临时空白文件
		zipFile = new File(zipFilePath);
		if (!zipFile.canRead()) {
			try {
				zipFile.createNewFile();
			} catch (IOException e) {

			}
		}
		ZipOutputStream out = null;
		try {
			out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
		} catch (FileNotFoundException e) {

		}
		out.setEncoding(ConstantUtils.ENCODER_GBK);
		out.setMethod(ZipOutputStream.DEFLATED);
		try {
			try {
				zipFiles(out, new File(filesPath), ConstantUtils.EMPTY_STRING);
			} finally {
				out.close();
			}
		} catch (IOException e) {

		}
	}

	private static void zipFiles(ZipOutputStream out, File f, String base) throws IOException {
		if (f.isDirectory()) {
			File[] fl = f.listFiles();
			out.putNextEntry(new ZipEntry(base + File.separator));
			base = base.length() == 0 ? ConstantUtils.EMPTY_STRING : base + File.separator;
			for (int i = 0; i < fl.length; i++) {
				zipFiles(out, fl[i], base + fl[i].getName());
			}
		} else {
			out.putNextEntry(new ZipEntry(base));
			BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
			int len = 0;
			byte[] b = new byte[4082];
			while (-1 != (len = in.read(b))) {
				out.write(b, 0, len);
			}
			in.close();
		}
	}

	/**
	 * 删除目录及目录下文件
	 * 
	 * @param filePath
	 *            目录路径
	 */
	public static void deleteFile(String filePath) {
		File f = new File(filePath);
		if (f.exists() && f.isDirectory()) {
			File delFiles[] = f.listFiles();
			for (File file : delFiles) {
				deleteFile(file.getAbsolutePath());
			}
		}
		if (!f.delete()) {

		}
	}

	/**
	 * 文件分割
	 * 
	 * @param file
	 *            被分割的文件
	 * @param outPutPath
	 *            文件输入路径
	 * @return 分割后的文件路径
	 * @throws IOException
	 */
	public static List<String> splitToSmallFiles(File file, String outPutPath, int splitSize) throws IOException {
		Assert.notNull(file, "分割文件为空");
		Assert.hasText(outPutPath, "输入文件路径为空");

		final String join = "_";
		int filePointer = 0;
		// 最大4M分割
		int maxSize = splitSize * 1024 * 1024;

		List<String> listSplitFilePath = new ArrayList<String>();

		BufferedWriter writer = null;
		BufferedReader reader = new BufferedReader(new FileReader(file));
		StringBuilder buffer = new StringBuilder();
		String line = reader.readLine();

		String splitFilePath = null;
		while (null != line) {
			buffer.append(line);
			// 文件分割
			if (buffer.length() >= maxSize) {
				// 临时文件名
				splitFilePath = outPutPath + join + filePointer;
				File temp = new File(outPutPath);
				if (!temp.canRead()) {
					if (!temp.mkdirs()) {
						throw new IOException();
					}
				}
				temp = new File(splitFilePath);
				if (!temp.canRead()) {
					if (!temp.createNewFile()) {
						throw new IOException();
					}
				}

				writer = new BufferedWriter(new FileWriter(temp));
				writer.write(new String(buffer));
				writer.flush();
				writer.close();
				filePointer++;

				buffer = new StringBuilder();

				listSplitFilePath.add(splitFilePath);
			}
			line = reader.readLine();

		}

		// 最后剩下的不足4M的文件
		splitFilePath = outPutPath + join + filePointer;

		writer = new BufferedWriter(new FileWriter(splitFilePath));

		listSplitFilePath.add(splitFilePath);

		writer.write(new String(buffer));

		writer.flush();
		writer.close();
		reader.close();

		return listSplitFilePath;
	}

	/**
	 * 读取文件内容
	 * 
	 * @param filePath
	 *            文件路径
	 * @return 文件内容
	 * @throws IOException
	 */
	public static String getFileContent(String filePath) throws IOException {
		Assert.hasText(filePath, "文件路径为空");
		File file = new File(filePath);
		// 文件存在
		if (file.canRead()) {
			return getFileContent(file);
		}
		return null;
	}

	/**
	 * 读取文件内容
	 * 
	 * @param file
	 *            文件
	 * @return 文件内容
	 * @throws IOException
	 */
	public static String getFileContent(File file) throws IOException {
		// 文件不存在
		if (!file.canRead()) {
			return null;
		}
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
		StringBuffer buff = new StringBuffer();
		String line = null;
		while (null != (line = br.readLine())) {
			buff.append(line);
		}

		br.close();

		return buff.toString();
	}

	public static void main(String[] args) throws Exception {
		deleteFile("c:/abc.txt");
	}

	/**
	 * 返回是否是合法的文件后缀
	 * 
	 * @param legitimateSuffix
	 *            合法的后缀集
	 * @param suffix
	 *            当前文件后缀
	 * @return 合法：True，不合法：False
	 */
	public static boolean legitimateFileSuffix(String[] legitimateSuffix, String suffix) {
		Assert.notNull(legitimateSuffix, "合法后缀集不可为空");
		Assert.notNull(suffix, "文件后缀不可为空");
		for (String ls : legitimateSuffix) {
			if (suffix.equalsIgnoreCase(ls.trim())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 返回系统默认的是否是合法的文件后缀
	 * 
	 * @param suffix
	 *            当前文件后缀
	 * @return 合法：True，不合法：False
	 */
	public static boolean defaultLegitimateFileSuffix(String suffix) {
		String legitimateSuffix = getProperties(ConstantUtils.DEFAULT_UPLOAD_FILE_SUFFIX);
		return legitimateFileSuffix(legitimateSuffix, suffix);
	}

	/**
	 * 返回系统默认的是否是合法的图片文件后缀
	 * 
	 * @param suffix
	 *            当前文件后缀
	 * @return 合法：True，不合法：False
	 */
	public static boolean defaultLegitimateImageSuffix(String suffix) {
		String legitimateSuffix = getProperties(ConstantUtils.DEFAULT_UPLOAD_IMAGE_SUFFIX);
		return legitimateFileSuffix(legitimateSuffix, suffix);
	}

	/**
	 * 根据HttpServletResponse响应流和文件对象下载文件
	 * 
	 * @param response
	 *            响应流
	 * @param downloadFile
	 *            下载文件对象
	 * @param fileName
	 *            文件名
	 * @throws IOException
	 *             IO异常
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	public static void download(HttpServletResponse response, File downloadFile, String fileName) {
		Assert.notNull(downloadFile, "下载文件不能为空");

		BufferedInputStream buffInput = null;
		try {
			buffInput = new BufferedInputStream(new FileInputStream(downloadFile));
		} catch (FileNotFoundException e) {

		}
		byte[] inputByte = new byte[2048 * 10];

		// 重置响应流
		response.reset();
		response.setCharacterEncoding(ConstantUtils.ENCODER_UTF_8);
		// 设置响应流的响应类型
		// response.setContentType("application/x-rar-compressed");
		String suffix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
		try {
			response.setContentType(getDownLoadMiniContentType(suffix));
		} catch (IllegalArgumentException e) {

		} catch (IllegalAccessException e) {

		}
		// 进行字符编码
		try {
			fileName = new String(fileName.getBytes(ConstantUtils.ENCODER_UTF_8), "ISO_8859_1");
		} catch (UnsupportedEncodingException e) {

		}
		response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
		// 添加头信息，指定文件大小，让浏览器能够显示下载进度
		response.setHeader("Content-Length", String.valueOf(downloadFile.length()));
		int len = 0;

		try {
			try {
				while ((len = buffInput.read(inputByte)) > 0) {
					response.getOutputStream().write(inputByte, 0, len);
				}
			} finally {
				buffInput.close();
				response.getOutputStream().flush();
				response.getOutputStream().close();
			}
		} catch (IOException e) {

		}
	}

	/**
	 * 根据文件后缀返回相应的Mini格式
	 * 
	 * @param suffix
	 *            文件后缀
	 * @return ContentType类型
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	private static String getDownLoadMiniContentType(String suffix) throws IllegalArgumentException,
			IllegalAccessException {
		Map<String, String[]> miniConfig = getMiniConfig();
		Set<Map.Entry<String, String[]>> entry = miniConfig.entrySet();
		for (Map.Entry<String, String[]> entry2 : entry) {
			String key = entry2.getKey().trim();
			String[] value = entry2.getValue();
			for (String val : value) {
				if (suffix.equals(val.trim())) {
					return key;
				}
			}
		}
		return "application/force-download";
	}

	/**
	 * 系统支持Mini配置
	 * 
	 * @return
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	private static Map<String, String[]> getMiniConfig() throws IllegalArgumentException, IllegalAccessException {
		if (miniConfig.isEmpty()) {
			// 正则匹配常量类中 Mini 常量
			Field[] f = ConstantUtils.class.getFields();
			Pattern p = Pattern.compile("^DEFAULT_DOWNLOAD_MINI_");
			Matcher m = null;
			for (Field field : f) {
				m = p.matcher(field.getName());
				if (m.find()) {
					splitMiniConfig(miniConfig, FileUtils.getProperties((String) field.get(field.getName())));
				}
			}

		}

		return miniConfig;
	}

	private static void splitMiniConfig(Map<String, String[]> miniConfig, String temp) {
		final String split = "_";
		miniConfig.put(temp.split(split)[0].trim(), temp.split(split)[1].split(ConstantUtils.SPLIT_KEY));
	}

	/**
	 * 根据上传文件路径和目标文件路径保存上传文件
	 * 
	 * @param source
	 *            源文件路径
	 * @param target
	 *            目标文件路径
	 */
	public static void save(String source, String target) throws IOException {
		Assert.notNull(source, "源文件路径为空");
		Assert.notNull(target, "目标文件路径为空");

		save(new File(source), new File(target));
	}

	/**
	 * 根据上传文件对象和目标文件对象保存上传文件
	 * 
	 * @param sourceFile
	 *            源文件文件
	 * @param targetFile
	 *            目标文件文件
	 */
	public static void save(File sourceFile, File targetFile) throws IOException {
		Assert.notNull(sourceFile, "源文件路径为空");
		Assert.notNull(targetFile, "目标文件路径为空");
		if (!targetFile.canRead()) {
			if (!targetFile.createNewFile()) {
				throw new IOException("创建空文件失败");
			}
		}
		FileCopyUtils.copy(sourceFile, targetFile);
	}

	/**
	 * 保存文件
	 * 
	 * @param sourceFile
	 *            源目标文件
	 * @param targetFile
	 *            目录文件路径
	 */
	public static void save(InputStream sourceFile, String targetDirectory, String targetFile) throws IOException {
		Assert.notNull(sourceFile, "源文件路径为空");
		Assert.notNull(targetDirectory, "目标目录文件路径为空");
		Assert.notNull(targetFile, "目标文件路径为空");

		File target = new File(targetDirectory);
		if (!target.exists()) {
			// 当文件不存在时创建
			if (!target.mkdirs()) {
				throw new IOException("目录创建失败");
			}
		}

		target = new File(targetFile);
		if (!target.exists()) {
			// 当文件不存在时创建
			if (!target.createNewFile()) {
				throw new IOException("目标文件创建失败");
			}
		}

		// 源数据流
		BufferedInputStream bis = new BufferedInputStream(sourceFile);
		// 目录数据流
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetDirectory + "/" + targetFile));

		byte[] b = new byte[2048];
		int len = 0;
		while (-1 != (len = bis.read(b))) {
			bos.write(b, 0, len);
		}
		// 流关闭
		bos.close();
		bis.close();
	}

	/**
	 * 将一段字符串给予指定的编码转换，如UTF-8
	 * 
	 * @param conversionString
	 *            需转换的字符串
	 * @param coding
	 *            编码方式
	 * @return 编码后的字符串
	 * @throws UnsupportedEncodingException
	 *             转换异常
	 */
	public static String conversionStringCoding(String conversionString, String coding)
			throws UnsupportedEncodingException {
		return URLEncoder.encode(conversionString, coding);
	}

	/**
	 * 将指定文件读入流中并进行编码
	 * 
	 * @param conversionPath
	 *            读取文件的路径
	 * @param coding
	 *            编码方式
	 * @return 编码后的字符串
	 * @throws IOException
	 *             IO异常
	 */
	public static String conversionFileCoding(String conversionPath, String coding) throws IOException {
		Resource res = new ClassPathResource(conversionPath);
		EncodedResource encRes = new EncodedResource(res, coding);
		return FileCopyUtils.copyToString(encRes.getReader());
	}

	/**
	 * 返回根据文件根路径+临时文件夹+模块名+用户名+随机文件名的文件路径，人工输入随机文件名
	 * 
	 * @param request
	 *            HttpServlet请求
	 * @param moduleName
	 *            模块名
	 * @param loginName
	 *            当前用户登陆名
	 * @param fileName
	 *            文件随机名
	 * @return 文件路径
	 */
	public static String getRandomFileName(HttpServletRequest request, String moduleName, String loginName,
			String fileName) {
		return new StringBuffer(request.getContextPath()).append(ConstantUtils.FILE_PATH_SPLIT).append("upload")
				.append(ConstantUtils.FILE_PATH_SPLIT).append(moduleName).append(ConstantUtils.FILE_PATH_SPLIT)
				.append(fileName).toString();
	}

	/**
	 * 返回根据文件根路径+临时文件夹+模块名+用户名+随机文件名的文件路径，系统设定随机文件名
	 * 
	 * @param request
	 *            HttpServlet请求
	 * @param moduleName
	 *            模块名
	 * @param loginName
	 *            当前用户登陆名
	 * @return 文件路径
	 */
	public static String getRandomFileName(HttpServletRequest request, String moduleName, String loginName) {
		return getRandomFileName(request, moduleName, loginName, UUID.randomUUID().toString());
	}

	/**
	 * 返回根据文件根路径+临时文件夹+模块名+用户名+随机文件名的文件对象，人工输入随机文件名
	 * 
	 * @param request
	 *            HttpServlet请求
	 * @param moduleName
	 *            模块名
	 * @param loginName
	 *            当前用户登陆名
	 * @param fileName
	 *            文件随机名
	 * @return 文件对象
	 */
	public static File getRandomFile(HttpServletRequest request, String moduleName, String loginName, String fileName) {
		return new File(getRandomFileName(request, moduleName, loginName, fileName));
	}

	/**
	 * 返回根据文件根路径+临时文件夹+模块名+用户名+随机文件名的文件对象，系统自动生成随机文件名
	 * 
	 * @param request
	 *            HttpServlet请求
	 * @param moduleName
	 *            模块名
	 * @param loginName
	 *            当前用户登陆名
	 * @param fileName
	 *            文件随机名
	 * @return 文件对象
	 */
	public static File getRandomFile(HttpServletRequest request, String moduleName, String loginName) {
		return getRandomFile(request, moduleName, loginName, UUID.randomUUID().toString());
	}

	/**
	 * 返回文件大小字符串形式,保留两位小数
	 * 
	 * @param length
	 *            文件大小
	 * @return 文件大小字符串形式
	 */
	public static String getFileLength(long length) {
		if (1024 > length) {
			return length + " b";
			// 保留两位小数
		} else if (1024 * 1024 > length) {
			return Math.round(length / 1024 * 100) / 100.0 + " kb";
		} else if (1024 * 1024 * 1024 > length) {
			return Math.round(length / 1024 / 1024 * 100) / 100.0 + " mb";
		}

		return ConstantUtils.EMPTY_STRING;
	}

}
